package com.msc.sdm.services.impl;

import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Priority;
import org.apache.myfaces.shared.util.ArrayUtils;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.msc.sdm.ana.authentication.AuthenticationManager;
import com.msc.sdm.ana.authorization.AuthorizationException;
import com.msc.sdm.ana.authorization.AuthorizationManager;
import com.msc.sdm.ana.authorization.AuthorizationManagerFactory;
import com.msc.sdm.ana.authorization.CaptureLoginDataManager;
import com.msc.sdm.ana.authorization.CaptureLoginDataManagerFactory;
import com.msc.sdm.application.Core;
import com.msc.sdm.application.ExecutionContext;
import com.msc.sdm.application.NavigationTreeStates;
import com.msc.sdm.application.SdmSessionManager;
import com.msc.sdm.application.SdmUserSession;
import com.msc.sdm.application.SdmVersion;
import com.msc.sdm.application.ServerSideServiceProvider;
import com.msc.sdm.config.Configuration;
import com.msc.sdm.config.ObjectTypeConfig;
import com.msc.sdm.db.DBException;
import com.msc.sdm.db.DataClass;
import com.msc.sdm.db.DatabaseConnection;
import com.msc.sdm.db.DbUtils;
import com.msc.sdm.db.InstanceHandle;
import com.msc.sdm.db.InstanceList;
import com.msc.sdm.db.ManyReferenceHandle;
import com.msc.sdm.db.ObjectNotFoundException;
import com.msc.sdm.db.PermissionDeniedException;
import com.msc.sdm.db.UniqueId;
import com.msc.sdm.eventnotification.SmNotification;
import com.msc.sdm.exception.AuthenticationException;
import com.msc.sdm.exception.InvalidRoleException;
import com.msc.sdm.exception.InvalidRoleTypeException;
import com.msc.sdm.exception.MessageHolder;
import com.msc.sdm.exception.NullSdmUserSessionException;
import com.msc.sdm.exception.NullSdmUserSessionKeyException;
import com.msc.sdm.exception.SdmException;
import com.msc.sdm.exception.UnknownPropertyException;
import com.msc.sdm.exception.ValidationException;
import com.msc.sdm.generic.utils.StringEncryptDecrypt;
import com.msc.sdm.i18n.I18NUtil;
import com.msc.sdm.ic.pub.SimMgrStringArray;
import com.msc.sdm.ic.pub.inproc.SimMgrStringArrayImpl;
import com.msc.sdm.licensing.LicenseFactory;
import com.msc.sdm.licensing.UserLicensing;
import com.msc.sdm.logging.events.UserLoginFailedEvent;
import com.msc.sdm.logging.events.UserLoginSuccessfulEvent;
import com.msc.sdm.logging.events.UserLogoutEvent;
import com.msc.sdm.sdmobject.HeartbeatTracker;
import com.msc.sdm.sdmobject.Process;
import com.msc.sdm.sdmobject.ProcessStep;
import com.msc.sdm.sdmobject.User;
import com.msc.sdm.sdmobject.UserProfile;
import com.msc.sdm.sdmobject.UserSession;
import com.msc.sdm.services.AuthorizationService;
import com.msc.sdm.services.LoggingService;
import com.msc.sdm.services.PreferencesService;
import com.msc.sdm.services.SessionService;
import com.msc.sdm.services.StateManagementService;
import com.msc.sdm.tree.TreeNode;
import com.msc.sdm.txn.impl.TransactionalVoidCommand;
import com.msc.sdm.util.SDMUtil;
import com.msc.sdm.util.SdmLogger;
import com.msc.sdm.util.ana.AnAUtil;
import com.msc.sdm.vo.DbObject;
import com.msc.sdm.vo.DbObjectList;
import com.msc.sdm.vo.UserAttributes;
import com.msc.sdm.vo.state.tree.TreeState;
import com.msc.sdm.vo.state.tree.TreeView;
import com.msc.sdm.vo.state.tree.TreeViews;
import com.msc.sdm.web.util.NameValue;

public class SessionLocalService
  implements SessionService
{
  private static String webAccessType = "WebAccess";
  
  public String logon(String paramString1, String paramString2, NameValue[] paramArrayOfNameValue1, NameValue[] paramArrayOfNameValue2)
    throws ValidationException, AuthenticationException, AuthorizationException
  {
    return logon(paramString1, paramString2, null, paramArrayOfNameValue1, paramArrayOfNameValue2, null);
  }
  
  private String logon(String paramString1, String paramString2, String paramString3, NameValue[] paramArrayOfNameValue1, NameValue[] paramArrayOfNameValue2, String paramString4)
    throws ValidationException, AuthenticationException, AuthorizationException
  {
    String str = logonAndValidateUser(paramString1, paramString2, paramString3, true, paramArrayOfNameValue1, paramArrayOfNameValue2, paramString4);
    ExecutionContext.getInstance().setSessionKey(str, false);
    
    SdmUserSession localSdmUserSession = ExecutionContext.getInstance().getUserSession();
    localSdmUserSession.initPreferencesInfoInSession();
    localSdmUserSession.init();
    
    initializeStates(localSdmUserSession);
    
    return str;
  }
  
  @Transactional(propagation=Propagation.REQUIRED, noRollbackFor={AuthorizationException.class}, rollbackFor={Throwable.class})
  public String logon(String paramString1, String paramString2)
    throws ValidationException, AuthenticationException, AuthorizationException
  {
    return logon(paramString1, paramString2, null);
  }
  
  @Transactional(propagation=Propagation.REQUIRED, noRollbackFor={AuthorizationException.class}, rollbackFor={Throwable.class})
  public String logon(String paramString1, String paramString2, String paramString3)
    throws ValidationException, AuthenticationException, AuthorizationException
  {
    return logon(paramString1, paramString2, paramString3, null, null, null);
  }
  
  @Transactional(propagation=Propagation.REQUIRED, noRollbackFor={AuthorizationException.class}, rollbackFor={Throwable.class})
  public String logon(String paramString1, String paramString2, String paramString3, String paramString4)
    throws ValidationException, AuthenticationException, AuthorizationException
  {
    return logon(paramString1, paramString2, paramString3, null, null, paramString4);
  }
  
  @Transactional(propagation=Propagation.REQUIRED, rollbackFor={Throwable.class})
  public String logonFromIC(String paramString1, String paramString2)
    throws ValidationException, AuthenticationException, AuthorizationException
  {
    StringEncryptDecrypt localStringEncryptDecrypt = new StringEncryptDecrypt(SdmLogger.getServicesLogger());
    String str1 = localStringEncryptDecrypt.decrypt(paramString1);
    String str2 = localStringEncryptDecrypt.decrypt(paramString2);
    
    return logon(str1, str2, "IntegratedClientLogin");
  }
  
  @Transactional(propagation=Propagation.REQUIRED, rollbackFor={Throwable.class})
  public String logonFromActionRunner(String paramString1, String paramString2)
    throws ValidationException
  {
    Core localCore = Core.getCore();
    if (SdmLogger.getServicesLogger().isEnabledFor(Priority.DEBUG)) {
      SdmLogger.getServicesLogger().debug("Entering logon() process ID = " + paramString1);
    }
    ExecutionContext.getInstance().setUserSession(SdmUserSession.newSession("Root"));
    
    boolean bool = validateMac(paramString1, paramString2);
    if (!bool)
    {
    	Base64 localObject1 = new Base64();
      byte[] localObject2 = ((Base64)localObject1).encode(paramString1.getBytes());
      String localObject3 = new String((byte[])localObject2);
      if (paramString2.equals(localObject3)) {
        bool = true;
      }
    }
    if (SdmLogger.getServicesLogger().isEnabledFor(Priority.DEBUG)) {
      SdmLogger.getServicesLogger().debug("Returning from logon() valid = " + Boolean.toString(bool));
    }
    if (!bool) {
      throw new ValidationException("error.actionRunner.invalidMessageAuthCode", new Object[0]);
    }
    Object localObject1 = ExecutionContext.getInstance().getDatabaseConnection();
    
    Object localObject2 = ((DatabaseConnection)localObject1).getDatabase().getSchema().getDataClassByQualifiedName("com.msc.sdm.sdmobject.Process");
    
    Object localObject3 = new UniqueId(paramString1);
    
    Process localProcess = new Process(((DatabaseConnection)localObject1).getInstanceById((DataClass)localObject2, (UniqueId)localObject3));
    
    UserProfile localUserProfile = localProcess.getUserProfile();
    String str1 = localUserProfile.getName();
    User localUser = localProcess.getOwner();
    String str2 = localUser.getName();
    if (SdmLogger.getServicesLogger().isEnabledFor(Priority.DEBUG)) {
      SdmLogger.getServicesLogger().debug("logon() user name of process is: " + str2);
    }
    SdmUserSession localSdmUserSession = manufactureUserSession(localUser, localUserProfile);
    
    String[] arrayOfString = localSdmUserSession.getUserAttributes().getSecurityLabels();
    
    AuthorizationService localAuthorizationService = ServerSideServiceProvider.getServiceProvider().getAuthorizationService();
    localAuthorizationService.createSecurityLabels(null, arrayOfString);
    
    ((DatabaseConnection)localObject1).setCurrentUser(str2);
    ((DatabaseConnection)localObject1).setCurrentUserProfile(str1);
    
    String str3 = localCore.getSessionManager().registerSession(localSdmUserSession);
    SdmLogger.getServicesLogger().info(I18NUtil.getDebugMsgCatalog().getMsg("msg.session.creatingSession", str2, str1));
    
    ExecutionContext.getInstance().clearUserSession();
    
    localSdmUserSession.setServerLicenseID(localCore.getServerLicenseID());
    return str3;
  }
  
  @Transactional(propagation=Propagation.REQUIRED, rollbackFor={Throwable.class})
  public String logonFromTrustedClient(String paramString1, String paramString2)
    throws ValidationException, AuthenticationException, AuthorizationException
  {
    if (!Core.getConfig().isTrustedClientAllowed()) {
      throw new SdmException("Trusted Client Login not enabled");
    }
    if (!"DieserTextSollteNichtLesbarSein".equals(paramString2)) {
      throw new SdmException("We don't trust this client");
    }
    String str = logonAndValidateUser(paramString1, null, false, null, null);
    ExecutionContext localExecutionContext = ExecutionContext.getInstance();
    localExecutionContext.setSessionKey(str, false);
    
    SdmUserSession localSdmUserSession = localExecutionContext.getUserSession();
    localSdmUserSession.initPreferencesInfoInSession();
    
    return str;
  }
  
  private boolean validateMac(String paramString1, String paramString2)
  {
    boolean bool = false;
    ObjectTypeConfig localObjectTypeConfig = Core.getConfig().getObjectTypeByName("Process");
    DbObject localDbObject = new DbObject(new UniqueId(paramString1), localObjectTypeConfig.getId());
    SDMUtil.waitForInsertedObjectAndLock(localDbObject);
    
    SdmLogger.getServicesLogger().debug("VALIDATE MAC FOR PROCESS " + paramString1);
    SdmLogger.getServicesLogger().debug("MAC " + paramString2);
    try
    {
      Process localProcess = new Process(SDMUtil.retrieveInstance(localDbObject));
      InstanceList localInstanceList = localProcess.getProcessSteps();
      try
      {
        while (localInstanceList.next())
        {
          ProcessStep localProcessStep = new ProcessStep(localInstanceList.getInstance());
          if (localProcessStep.getStepName().equals("execute"))
          {
            localProcessStep.getHandle().reload();
            String str = localProcessStep.getMac();
            if ((str != null) && (str.length() > 0) && 
              (str.equals(paramString2)))
            {
              localProcessStep.setMac("");
              localProcessStep.save();
              bool = true;
            }
            else if (str == null)
            {
              SdmLogger.getServicesLogger().debug(I18NUtil.getDebugMsgCatalog().getMsg("error.SessionService.nullMac", localProcess
                .getId()));
            }
            else if (str.length() == 0)
            {
              SdmLogger.getServicesLogger().debug(I18NUtil.getDebugMsgCatalog().getMsg("error.SessionService.blankMac", localProcess
                .getId()));
            }
            else
            {
              SdmLogger.getServicesLogger().debug(I18NUtil.getDebugMsgCatalog().getMsg("error.SessionService.mismatchedMac", localProcess
              
                .getId()));
            }
          }
        }
      }
      finally
      {
        localInstanceList.close();
      }
    }
    catch (SdmException localSdmException)
    {
      SdmLogger.getServicesLogger().error(I18NUtil.getDebugMsgCatalog().getMsg("error.sdmexception.msg", localSdmException
        .getLocalizedMessage()), localSdmException);
    }
    return bool;
  }
  
  private String logonAndValidateUser(String paramString1, String paramString2, boolean paramBoolean, NameValue[] paramArrayOfNameValue1, NameValue[] paramArrayOfNameValue2)
    throws ValidationException, AuthenticationException, AuthorizationException
  {
    return logonAndValidateUser(paramString1, paramString2, null, paramBoolean, paramArrayOfNameValue1, paramArrayOfNameValue2, null);
  }
  
  private String logonAndValidateUser(String paramString1, String paramString2, String paramString3, boolean paramBoolean, NameValue[] paramArrayOfNameValue1, NameValue[] paramArrayOfNameValue2, String paramString4)
    throws ValidationException, AuthenticationException, AuthorizationException
  {
	  
    String[] arrayOfString1 = null;
    String[] arrayOfString2 = null;
    AuthenticationManager localAuthenticationManager = null;
    
    AuthorizationService localAuthorizationService = ServerSideServiceProvider.getServiceProvider().getAuthorizationService();
    
    LoggingService localLoggingService = ServerSideServiceProvider.getServiceProvider().getLoggingService();
    
    Core localCore = Core.getCore();
    Configuration localConfiguration = localCore.getConfiguration();
    if ((paramString1 == null) || (paramString1.length() == 0))
    {
      String str1 = "error.logon.usernamenullorblank";
      
      SdmLogger.getServicesLogger().error(I18NUtil.getDebugMsgCatalog().getMsg(str1));
      
      fireUserLoginFailedEvent(paramString1, str1, new String[0]);
      
      throw new ValidationException(str1, new Object[0]);
    }
    paramString1 = SDMUtil.stringToUserId(paramString1);
    if (SdmLogger.getServicesLogger().isEnabledFor(Priority.DEBUG)) {
      SdmLogger.getServicesLogger().debug("Entering logonAndValidateUser() username = " + paramString1);
    }
    if ((paramBoolean) && (localConfiguration.getManagedSecurity().equals("AMS")))
    {
      boolean bool1 = localCore.getSessionManager().authenticate(paramString1, paramString2);
      if (SdmLogger.getServicesLogger().isEnabledFor(Priority.DEBUG)) {
        SdmLogger.getServicesLogger().debug("AMS: Returning from logonAndValidateUser() valid = " + bool1);
      }
      if (!bool1)
      {
    	  String localObject1 = "error.login.invalid";
        fireUserLoginFailedEvent(paramString1, (String)localObject1, new String[] { paramString1 });
        
        throw new AuthenticationException(null, (String)localObject1, new Object[] { paramString1 });
      }
    }
    HttpServletRequest localHttpServletRequest = ExecutionContext.getInstance().getHttpServletRequest();
    if ((localHttpServletRequest != null) && (paramBoolean) && (localConfiguration.getManagedSecurity().equals("CMS")))
    {
    	String localObject1 = localHttpServletRequest.getRemoteUser();
      if (localObject1 == null)
      {
        boolean bool2 = localCore.getSessionManager().authenticate(paramString1, paramString2);
        if (SdmLogger.getServicesLogger().isEnabledFor(Priority.DEBUG)) {
          SdmLogger.getServicesLogger().debug("CMS: Returning from logonAndValidateUser() valid = " + bool2);
        }
        if (!bool2)
        {
        	String     localObject2 = "error.username_password.invalid";
          fireUserLoginFailedEvent(paramString1, (String)localObject2, new String[] { paramString1 });
          
          throw new AuthenticationException(paramString1);
        }
      }
    }
    ExecutionContext.getInstance().clearUserSession();
    DatabaseConnection localObject1 = ExecutionContext.getInstance().getDatabaseConnection();
    User localUser;
    
    //------------------------------------------------------------------------------------------------------------------------------
    
    //--------------------------------
    // TODO switch user to CommonUser 
    HttpServletRequest request = ExecutionContext.getInstance().getHttpServletRequest();
    String f = request.getParameter( "f" );
	if( StringUtils.isNotBlank( f ) &&  "ENOVIA".equals( f ) ) {
		paramString1 = "CommonUser" ;
	}
    //--------------------------------
    
    if( !User.checkUniqueName( localObject1 , paramString1 ) ) {
    	User cae1 = User.lookupByUniqueName( localObject1 , "CAE" );
    	String cae1Des = cae1.getDescription();
//System.out.println( "---->>" + cae1Des );
		
		String loginUserName = "CommonUser";
    	if( StringUtils.isNotBlank( cae1Des ) ) {
    		String[] cae1Users = StringUtils.split( cae1Des );
    		if( ArrayUtils.contains(cae1Users , paramString1 ) ) {
    			loginUserName = "CAE" ;
    		} 
    	} 
    	paramString1 = loginUserName ;
    };
    
    try{
      localUser = User.lookupByUniqueName( localObject1, paramString1);
      String str2;
      if ((!paramString1.equals(SDMUtil.getSimManUserName())) && 
        (localAuthorizationService.ageUserAccounts(null, new DbObjectList(SDMUtil.createDbObject(localUser.getHandle())))))
      {
        str2 = "error.userAccount.expired";
        fireUserLoginFailedEvent(paramString1, str2, new String[] { paramString1 });
        
        throw new AuthorizationException(null, str2, new Object[] { paramString1 });
      }
      if (!localUser.getIsActive()){
        str2 = "error.user.inactive";
        fireUserLoginFailedEvent(paramString1, str2, new String[] { paramString1 });
        
        throw new AuthorizationException(null, str2, new Object[] { paramString1 });
      }
    }
    catch (ObjectNotFoundException localObjectNotFoundException1)
    {
      if (Core.getConfig().isUserAutoCreateAtLogin())
      {
        localUser = null;
      }
      else
      {
       String localObject3 = "error.invalid.user";
        fireUserLoginFailedEvent(paramString1, (String)localObject3, new String[] { paramString1 });
        
        throw new AuthenticationException(null, (String)localObject3, new Object[] { paramString1 });
      }
    }
    //------------------------------------------------------------------------------------------------------------------------------
    
    
    AuthorizationManager localAuthorizationManager = AuthorizationManagerFactory.getAuthorizationManager();
    UserProfile localObject2 = localAuthorizationManager.getUserProfile(paramString1);
    if (localUser == null){
    	DbObject   localObject3 = null;
      try
      {
        localObject3 = localAuthorizationService.createUser(null, paramString1, ( localObject2 )
          .getRole().getName(), false, false);
      }
      catch (ObjectNotFoundException|PermissionDeniedException localObjectNotFoundException2)
      {
        fireUserLoginFailedEvent(paramString1, localObjectNotFoundException2.getMessageKey(), localObjectNotFoundException2.getMessageArgs());
        
        throw new AuthenticationException(localObjectNotFoundException2);
      }
      catch (InvalidRoleTypeException|InvalidRoleException|DBException localInvalidRoleTypeException)
      {
        fireUserLoginFailedEvent(paramString1, ((MessageHolder)localInvalidRoleTypeException).getMessageKey(), ((MessageHolder)localInvalidRoleTypeException).getMessageArgs());
        
        throw new SdmException(localInvalidRoleTypeException);
      }
      localUser = new User(SDMUtil.retrieveInstance((DbObject)localObject3));
    }
    Object localObject3 = localUser.getAllowedUserProfiles();
    String[] arrayOfString3 = localAuthorizationManager.getAllowedUserProfilesForUser(paramString1);
    
    ((ManyReferenceHandle)localObject3).clear();
    for (String str3 : arrayOfString3)
    {
      InstanceHandle localInstanceHandle = UserProfile.lookupByUniqueName((DatabaseConnection)localObject1, str3).getHandle();
      if (!((ManyReferenceHandle)localObject3).contains(localInstanceHandle)) {
        ((ManyReferenceHandle)localObject3).add(localInstanceHandle);
      }
    }
  String tmpxxx = logonInternal(paramString1, paramString3);
    try
    {
      UserLicensing localUserLicensing = LicenseFactory.getUserLicensing(paramString1);
      localUserLicensing.handleLogin(paramString4);
    }
    catch (SdmException localSdmException)
    {
      logout((String)tmpxxx);
      throw localSdmException;
    }
    ExecutionContext.getInstance().setSessionKey(tmpxxx, false);
    SdmUserSession localSdmUserSession = ExecutionContext.getInstance().getUserSession();
    localSdmUserSession.setRestClientAppName(paramString4);
    
    localSdmUserSession.setLicenseCheckedOut(true);
    
    localAuthenticationManager = localCore.getAuthenticationManager();
    arrayOfString1 = Core.getConfig().getUserInfo();
    Object localObject5;
    if ((localAuthenticationManager != null) && (arrayOfString1 != null) && (arrayOfString1.length > 0))
    {
      arrayOfString2 = localAuthenticationManager.getUserInfoValues(paramString1, arrayOfString1);
      localObject5 = SDMUtil.getDbAttrName(arrayOfString1);
      localAuthorizationService.saveUserInfo(null, paramString1, arrayOfString2, (String[])localObject5);
    }
    if (localHttpServletRequest != null)
    {
      try
      {
        localObject5 = Core.getConfig().getProperty("ip.address.header.attribute");
      }
      catch (UnknownPropertyException localUnknownPropertyException)
      {
        localObject5 = "X-FORWARDED-FOR";
      }
      String str4 = localHttpServletRequest.getHeader((String)localObject5);
      if ((str4 == null) || (str4.length() == 0)) {
        str4 = localHttpServletRequest.getRemoteAddr();
      }
      localSdmUserSession.setClientIPAddress(str4);
    }
    return tmpxxx;
  }
  
  public String logonInternal(String paramString)
    throws ValidationException
  {
    return logonInternal(paramString, null);
  }
  
  public String logonInternal(String paramString1, String paramString2)
    throws ValidationException
  {
    Core localCore = Core.getCore();
    ExecutionContext localExecutionContext = ExecutionContext.getInstance();
    DatabaseConnection localDatabaseConnection = localExecutionContext.getDatabaseConnection();
    User localUser = User.lookupByUniqueName(localDatabaseConnection, paramString1);
    if ((paramString2 == null) || (paramString2.trim().length() == 0)) {
      paramString2 = "UserLogin";
    }
    SdmUserSession localSdmUserSession = manufactureUserSession(localUser, paramString2, null);
    
    String[] arrayOfString = localSdmUserSession.getUserAttributes().getSecurityLabels();
    
    AuthorizationService localAuthorizationService = ServerSideServiceProvider.getServiceProvider().getAuthorizationService();
    localAuthorizationService.createSecurityLabels(null, arrayOfString);
    
    String str1 = localSdmUserSession.getProfileName();
    localDatabaseConnection.setCurrentUser(paramString1);
    localDatabaseConnection.setCurrentUserProfile(str1);
    
    String str2 = localCore.getSessionManager().registerSession(localSdmUserSession);
    SdmLogger.getServicesLogger().info(I18NUtil.getDebugMsgCatalog().getMsg("msg.session.creatingSession", paramString1, str1));
    localSdmUserSession.setLicenseType(localUser.getLicenseType());
    localSdmUserSession.setServerLicenseID(localCore.getServerLicenseID());
    
    SdmLogger.getServicesLogger().info("User: '" + paramString1 + "' logged in successfully.");
    
    fireUserLoginSuccessfulEvent(SDMUtil.createDbObject(localUser.getHandle()), localSdmUserSession.getSessionId().toString());
    
    localExecutionContext.setUserSessionAndDontCloseConnection(localSdmUserSession);
    
    return str2;
  }
  
  private void fireUserLoginSuccessfulEvent(DbObject paramDbObject, String paramString)
  {
    String[] arrayOfString = { paramString };
    String str = UserLoginSuccessfulEvent.class.getName();
    
    UserLoginSuccessfulEvent localUserLoginSuccessfulEvent = new UserLoginSuccessfulEvent(str, arrayOfString, "User Login Successful", paramDbObject);
    
    new SmNotification().publishEventNoQuery(localUserLoginSuccessfulEvent, false);
  }
  
  private void fireUserLoginFailedEvent(final String paramString1, final String paramString2, final String... paramVarArgs)
  {
    new TransactionalVoidCommand()
    {
      public void doInTransaction()
      {
        String[] arrayOfString = new String[paramVarArgs.length + 2];
        arrayOfString[0] = paramString1;
        arrayOfString[1] = paramString2;
        for (int i = 0; i < paramVarArgs.length; i++) {
          arrayOfString[(i + 2)] = paramVarArgs[i];
        }
        String str = UserLoginFailedEvent.class.getName();
        
        UserLoginFailedEvent localUserLoginFailedEvent = new UserLoginFailedEvent(str, arrayOfString, "User Login Failed");
        
        new SmNotification().publishEventNoQuery(localUserLoginFailedEvent, false);
        DbUtils.throwIfOutOfTransaction();
      }
    }.executeNew();
  }
  
  private void fireUserLogoutEvent(DbObject paramDbObject, String paramString)
  {
    String[] arrayOfString = { paramString };
    String str = UserLogoutEvent.class.getName();
    
    UserLogoutEvent localUserLogoutEvent = new UserLogoutEvent(str, arrayOfString, "User Logged out", paramDbObject);
    
    new SmNotification().publishEventNoQuery(localUserLogoutEvent, false);
  }
  
  public SdmUserSession manufactureUserSession(User paramUser)
    throws ValidationException
  {
    return manufactureUserSession(paramUser, null);
  }
  
  public SdmUserSession manufactureUserSession(User paramUser, UserProfile paramUserProfile)
    throws ValidationException
  {
    return manufactureUserSession(paramUser, "RemoteJobLogin", paramUserProfile);
  }
  
  public SdmUserSession manufactureUserSession(User paramUser, String paramString, UserProfile paramUserProfile)
    throws ValidationException
  {
    String str = paramUser.getName();
    
    SdmSessionManager localSdmSessionManager = Core.getCore().getSessionManager();
    
    UserAttributes localUserAttributes = localSdmSessionManager.getSecurityAttributes(str);
    
    validateSecurityLabels(localUserAttributes.getSecurityLabels());
    
    AuthorizationManager localAuthorizationManager = AuthorizationManagerFactory.getAuthorizationManager();
    if (paramUserProfile == null) {
      paramUserProfile = localAuthorizationManager.getUserProfile(paramUser.getName());
    }
    String[] arrayOfString = localAuthorizationManager.getAllowedUserProfilesForUser(paramUser.getName());
    
    SdmUserSession localSdmUserSession = SdmUserSession.newSession(str);
    if (!Core.getConfig().isDatabaseUserProfileManagement()) {
      AnAUtil.updateUserProfileAndAllowedUserProfiles(paramUser, paramUserProfile, arrayOfString);
    }
    localSdmUserSession.setProfileName(paramUserProfile.getName());
    localSdmUserSession.setAllowedUserProfiles(arrayOfString);
    localSdmUserSession.setUserAttributes(localUserAttributes);
    localSdmUserSession.setSessionType(paramString);
    return localSdmUserSession;
  }
  
  void validateSecurityLabels(String[] paramArrayOfString)
    throws ValidationException
  {
    for (int i = 0; i < paramArrayOfString.length; i++)
    {
      String str = paramArrayOfString[i];
      int j = str.length();
      if ((j == 0) || 
        (Character.isWhitespace(str.charAt(0))) || 
        (Character.isWhitespace(str.charAt(j - 1))) || 
        (str.indexOf('\\') >= 0) || 
        (str.indexOf('\'') >= 0)) {
        throw new ValidationException("error.authentication.invalidSecurityLabel", new Object[] { str });
      }
    }
  }
  
  @Transactional(propagation=Propagation.REQUIRED, rollbackFor={Throwable.class})
  public void logout(String paramString)
  {
    logout(paramString, false);
  }
  
  private void logout(String paramString, boolean paramBoolean)
  {
    if (null == paramString) {
      return;
    }
    SdmUserSession localSdmUserSession = null;
    try
    {
      localSdmUserSession = Core.getCore().getSessionManager().lookupSession(paramString);
    }
    catch (SdmException localSdmException)
    {
      throw localSdmException;
    }
    SdmLogger.getServicesLogger().info(I18NUtil.getDebugMsgCatalog().getMsg("msg.session.removingSession", localSdmUserSession.getUserName(), localSdmUserSession
      .getProfileName(), localSdmUserSession.getLicenseType()));
    
    PreferencesService localPreferencesService = ServerSideServiceProvider.getServiceProvider().getPreferencesService();
    localPreferencesService.savePreferences(paramString);
    
    localSdmUserSession.removeAllUploadedFiles();
    
    ObjectTypeConfig localObjectTypeConfig = Core.getConfig().getObjectTypeByName("UserSession");
    
    UniqueId localUniqueId = localSdmUserSession.getSessionId();
    
    DatabaseConnection localDatabaseConnection = ExecutionContext.getInstance().getDatabaseConnection();
    
    InstanceHandle localInstanceHandle = localDatabaseConnection.getInstanceById(localObjectTypeConfig.getDataClass(), localUniqueId);
    
    UserSession localUserSession = new UserSession(localInstanceHandle);
    Date localDate = new Date();
    localUserSession.setLogoutTime(localDate);
    localUserSession.save();
    User localUser = localUserSession.getUser();
    localUser.setLastActivityTime(localDate);
    localUser.save();
    DbUtils.throwIfOutOfTransaction();
    
    persistStates(localSdmUserSession);
    if (localSdmUserSession.isLicenseCheckedOut())
    {
      String str = localSdmUserSession.getRestClientAppName();
      UserLicensing localUserLicensing = LicenseFactory.getUserLicensing(localSdmUserSession.getUserName());
      localUserLicensing.handleLogout(str);
    }
    Core.getCore().getSessionManager().removeSession(paramString);
    SdmLogger.getServicesLogger().info("User: '" + localSdmUserSession.getUserName() + "' logged off successfully.");
    fireUserLogoutEvent(SDMUtil.createDbObject(localUser.getHandle()), localUserSession.getId().toString());
  }
  
  protected String captureUserName(NameValue[] paramArrayOfNameValue1, NameValue[] paramArrayOfNameValue2)
    throws SdmException
  {
    CaptureLoginDataManager localCaptureLoginDataManager = CaptureLoginDataManagerFactory.getCaptureLoginDataManager(Core.getConfig().getAppConfig());
    
    return localCaptureLoginDataManager.captureUserName(paramArrayOfNameValue1, paramArrayOfNameValue2);
  }
  
  public void removeDuplicateUserSessions(String paramString)
    throws SdmException
  {
    List<String> localList = Core.getCore().getSessionManager().getDuplicateUserSessions(paramString);
    for (String str : localList) {
      logout(str);
    }
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public boolean isSessionKeyValid(String paramString)
  {
    SdmUserSession localSdmUserSession = null;
    try
    {
      localSdmUserSession = Core.getCore().getSessionManager().lookupSession(paramString);
    }
    catch (NullSdmUserSessionException|NullSdmUserSessionKeyException localNullSdmUserSessionException) {}
    return localSdmUserSession != null;
  }
  
  @Transactional(propagation=Propagation.REQUIRED, rollbackFor={Throwable.class})
  public void removeAllSessions()
    throws SdmException
  {
    List<String> localList = Core.getCore().getSessionManager().getAllSessions();
    for (String str : localList) {
      logout(str, false);
    }
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public String getServerVersion()
  {
    Core localCore = Core.getCore();
    return localCore.getVersion();
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public void validateClientVersion(double paramDouble)
    throws SdmException
  {
    SdmVersion localSdmVersion = new SdmVersion();
    localSdmVersion.validateClientVersion(paramDouble);
  }
  
  private void initializeStates(SdmUserSession paramSdmUserSession)
    throws SdmException
  {
    loadTreeStateInfo(paramSdmUserSession);
  }
  
  private void persistStates(SdmUserSession paramSdmUserSession)
    throws SdmException
  {
    persistTreeStateInfo(paramSdmUserSession);
  }
  
  private void persistTreeStateInfo(SdmUserSession paramSdmUserSession)
    throws SdmException
  {
    StateManagementService localStateManagementService = ServerSideServiceProvider.getServiceProvider().getStateManagementService();
    
    String[] arrayOfString = paramSdmUserSession.getAvailableTreeViews();
    
    TreeView[] arrayOfTreeView = new TreeView[arrayOfString.length];
    for (int i = 0; i < arrayOfString.length; i++)
    {
      String str1 = arrayOfString[i];
      
      NavigationTreeStates localNavigationTreeStates = paramSdmUserSession.getTreeViewsNavigationTreeStates(str1);
      
      TreeView localTreeView = localNavigationTreeStates.getPersistedTreeStates();
      
      TreeNode[] arrayOfTreeNode = paramSdmUserSession.getRootTreeNodes(str1);
      
      TreeState[] arrayOfTreeState = new TreeState[arrayOfTreeNode.length];
      for (int j = 0; j < arrayOfTreeNode.length; j++)
      {
        TreeNode localTreeNode = arrayOfTreeNode[j];
        
        String str3 = localTreeNode.getTreeNodeSpec().getTreeDef().getName();
        
        arrayOfTreeState[j] = new TreeState(str3, localTreeNode.getOpenPaths());
      }
      String str2 = localNavigationTreeStates.getActiveTab();
      if (((str2 == null) || (str2.length() == 0)) && 
        (localTreeView != null)) {
        str2 = localTreeView.getDefaultTree();
      }
      if (localTreeView == null)
      {
        localTreeView = new TreeView(str1, arrayOfTreeState, str2);
      }
      else
      {
        for (int k = 0; k < arrayOfTreeState.length; k++) {
          localTreeView.updateState(arrayOfTreeState[k]);
        }
        localTreeView.setDefaultTree(str2);
      }
      arrayOfTreeView[i] = localTreeView;
    }
    localStateManagementService.persistState(new TreeViews(arrayOfTreeView));
  }
  
  private void loadTreeStateInfo(SdmUserSession paramSdmUserSession)
    throws SdmException
  {
    StateManagementService localStateManagementService = ServerSideServiceProvider.getServiceProvider().getStateManagementService();
    
    TreeViews localTreeViews = (TreeViews)localStateManagementService.loadState(TreeViews.class.getName());
    if (localTreeViews != null)
    {
      TreeView[] arrayOfTreeView = localTreeViews.getTreeViews();
      for (int i = 0; i < arrayOfTreeView.length; i++)
      {
        TreeView localTreeView = arrayOfTreeView[i];
        String str = localTreeView.getViewName();
        
        NavigationTreeStates localNavigationTreeStates = paramSdmUserSession.getTreeViewsNavigationTreeStates(str);
        
        localNavigationTreeStates.setActiveTab(localTreeView.getDefaultTree());
        localNavigationTreeStates.setPersistedTreeStates(localTreeView);
      }
    }
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public String getUserName()
  {
    return ExecutionContext.getInstance().getUserSession().getUserName();
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public UserAttributes getUserAttributes()
  {
    return ExecutionContext.getInstance().getUserSession().getUserAttributes();
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public String getWebAccessType()
    throws SdmException
  {
    return webAccessType;
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public void setWebAccessType(String paramString)
    throws SdmException
  {
    webAccessType = paramString;
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public SimMgrStringArray getActiveSecurityLabels()
  {
    String[] arrayOfString = ExecutionContext.getInstance().getUserSession().getActiveSecurityLabels();
    return new SimMgrStringArrayImpl(arrayOfString);
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public boolean getActiveStateOfMonitor(String paramString)
  {
    boolean bool = false;
    if (Core.getCore() != null)
    {
      HeartbeatTracker localHeartbeatTracker = getHeartBeatTracker(paramString);
      if (localHeartbeatTracker.hasActive()) {
        bool = localHeartbeatTracker.getActive();
      }
    }
    return bool;
  }
  
  @Transactional(propagation=Propagation.REQUIRED, rollbackFor={Throwable.class})
  public void setActiveStateOfMonitor(String paramString, boolean paramBoolean)
  {
    HeartbeatTracker localHeartbeatTracker = getHeartBeatTracker(paramString);
    
    localHeartbeatTracker.setActive(paramBoolean);
    localHeartbeatTracker.save();
    DbUtils.throwIfOutOfTransaction();
    
    String str = paramBoolean ? "activated" : "de-activated";
    SdmLogger.getServicesLogger().info(paramString + " is being " + str);
  }
  
  private HeartbeatTracker getHeartBeatTracker(String paramString)
  {
    HeartbeatTracker localHeartbeatTracker = null;
    DatabaseConnection localDatabaseConnection = ExecutionContext.getInstance().getDatabaseConnection();
    try
    {
      localHeartbeatTracker = HeartbeatTracker.lookupByUniqueName(localDatabaseConnection, paramString);
    }
    catch (ObjectNotFoundException localObjectNotFoundException)
    {
      localHeartbeatTracker = HeartbeatTracker.allocateHeartbeatTracker(localDatabaseConnection);
      
      localHeartbeatTracker.setSubsystemID(paramString);
      localHeartbeatTracker.setBeatCount(0L);
      localHeartbeatTracker.setActive(true);
    }
    return localHeartbeatTracker;
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public DbObject getCurrentConfig()
  {
    ObjectTypeConfig localObjectTypeConfig = Core.getConfig().getObjectTypeByName("Configuration");
    String str = ExecutionContext.getInstance().getUserSession().getConfiguration().getConfigId();
    if (null != str)
    {
      UniqueId localUniqueId = new UniqueId(str);
      return new DbObject(localUniqueId, localObjectTypeConfig.getId());
    }
    return null;
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public String getClientIPAddress()
    throws SdmException
  {
    SdmUserSession localSdmUserSession = ExecutionContext.getInstance().getUserSession();
    return localSdmUserSession.getClientIPAddress();
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public String getProfileName()
  {
    return ExecutionContext.getInstance().getUserSession().getProfileName();
  }
  
  @Transactional(propagation=Propagation.SUPPORTS, rollbackFor={Throwable.class})
  public String[] getAllowedProfileNames()
  {
    return ExecutionContext.getInstance().getUserSession().getAllowedUserProfiles();
  }
  
  @Transactional(propagation=Propagation.REQUIRED, rollbackFor={Throwable.class})
  public void updateProfileName(String paramString)
  {
    ExecutionContext.getInstance().getUserSession().setProfileName(paramString);
    
    ExecutionContext.getInstance().setCurrentUserProfile(paramString);
    
    ExecutionContext.getInstance().getUserSession().setActionCacheNeedsUpdate(true);
    
    ExecutionContext.getInstance().getUserSession().updateUserProfileInAssociatedUserSessionInDb();
  }
}
